from config import Config
import BaseIO
from dmx.NetlinxDMX import NetlinxDMX
from osc.osc_io import oscIO
from interprocess.SystemData import SystemData
from interprocess.ServiceConnector import ServiceConnector

class olaLoader(type):
    ui_name = 'OLA (Open Lighting Architecture)'
    def __new__(self, *args, **kwargs):
        from dmx.OSCtoOLA import OSCtoOLAHost
        return OSCtoOLAHost(*args, **kwargs)
    
class CommDispatcher(BaseIO.BaseIO, Config):
    _confsection = 'Comm'
    io_classes = {'NetlinxDMX':NetlinxDMX, 'ola_IO':olaLoader}
    def __init__(self, **kwargs):
        BaseIO.BaseIO.__init__(self, **kwargs)
        Config.__init__(self, **kwargs)
        self.SystemData = SystemData()
        self.ServiceConnector = ServiceConnector(SystemData=self.SystemData)
        self.register_signal('io_update')
        #self.register_signal('new_ola_universe')
        self.dmx_io = {}
#        self.dmx_io = {'NetlinxDMX':NetlinxDMX(hostaddr='192.168.1.9', hostport=1998),
#                       'ola':olaIO()}
#        self.dmx_io['ola'].connect('new_universe', self.on_new_ola_universe)
        osc_kwargs = kwargs.get('osc_kwargs', {})
        osc_kwargs.update({'comm':self})
        self.osc_io = oscIO(**osc_kwargs)
        io_keys = self.get_conf('dmx_io', [])
        for key in io_keys:
            self.build_io(key, update_conf=False)
        #self.build_io('ola_IO', osc_io=self.osc_io, update_conf)
        self._hostaddr = self.get_conf('host_address')
        self._hostiface = self.get_conf('host_interface')
        
        
    @property
    def hostaddr(self):
        if self._hostaddr:
            return self._hostaddr
        return BaseIO.detect_usable_address()
        
    def build_io(self, io_type, **kwargs):
        cls = self.io_classes.get(io_type)
        update_conf = kwargs.get('update_conf', True)
        if cls:
            if io_type == 'ola_IO':
                kwargs.setdefault('osc_io', self.osc_io)
            self.dmx_io.update({io_type:cls(**kwargs)})
            self.emit('io_update', key=io_type)
            if update_conf:
                self.update_conf(dmx_io=self.dmx_io.keys())
                
    def remove_io(self, io_type, **kwargs):
        io = self.dmx_io.get(io_type)
        update_conf = kwargs.get('update_conf', True)
        if io:
            io.do_disconnect()
            io.unlink()
            del self.dmx_io[io_type]
            self.emit('io_update', key=io_type)
            if update_conf:
                self.update_conf(dmx_io=self.dmx_io.keys())
        
    def do_connect(self, **kwargs):
        self.osc_io.do_connect()
        for dmx in self.dmx_io.itervalues():
            dmx.do_connect()
        print 'comm connected'
        self.ServiceConnector.publish()
        self.connected = True
        
    def do_disconnect(self, **kwargs):
        for dmx in self.dmx_io.itervalues():
            dmx.do_disconnect()
        self.osc_io.do_disconnect()
        print 'comm disconnected'
        self.ServiceConnector.unpublish()
        self.connected = False

#    def on_new_universe(self, **kwargs):
#        univ = kwargs.get('universe')
#        ola = self.dmx_io['ola']
#        olauniv = ola.universes.get(univ.ola_universe_id)
#        if olauniv is not None:
#            olauniv.Universe = univ
            
    def on_new_ola_universe(self, **kwargs):
        self.emit('new_ola_universe', **kwargs)
